home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / chunky.lha / lib_chunky / lib-src / chunky.c < prev    next >
C/C++ Source or Header  |  1998-02-26  |  11KB  |  477 lines

  1. /*
  2. ** chunky.c V1.0
  3. ** -------------
  4. **
  5. ** Functions to init, render in, convert and free a chunky port
  6. **
  7. ** To have a bottleneck, compile with USE_AMIGA_OS defined ;)
  8. **
  9. ** TODO:
  10. ** I want to implement those pretty BltBitMap() functions
  11. ** with and without a mask.
  12. */
  13. #define   __CONSTLIBBASEDECL__  const
  14. #include  <graphics/gfx.h>
  15. #include  <graphics/GfxBase.h>
  16. #include  <proto/graphics.h>
  17. #include  <proto/exec.h>
  18. #include  <math.h>
  19. #include  "chunky.h"
  20.  
  21. // Set this to compile a 100% GfxCard compatible renderlib
  22. // But if you only want to use Amiga-Features, DO NOT set this,
  23. // because it's ten times as slow as if it's not set
  24. //
  25. // COMPARE: Be GfxCard compatible for 2.2769 seconds for a 640x480x8 display
  26. // OR     : Be fast (0.23 seconds ) and use this only for native amigas.
  27. //#define USE_AMIGA_OS
  28.  
  29. ///"int sptst( ... )"
  30. static inline int sptst( float x )
  31. {
  32.     int ret = 0;
  33.  
  34.     if( x < 0 )       ret = -1;
  35.     else if( x > 0 )  ret = 1;
  36.     else              ret = 0;
  37.     return( ret );
  38. }
  39. ///
  40. ///"struct ChunkyPort *InitChunkyPort( UWORD, UWORD )"
  41. struct ChunkyPort *InitChunkyPort( UWORD sx, UWORD sy )
  42. {
  43.     // Allocate and initialize the ChunkyPort for rendering
  44.     // operations
  45.  
  46.     struct  ChunkyPort  *cp;
  47.     if( cp = AllocVec( sizeof( struct ChunkyPort ) + ( sx * sy ), MEMF_ANY|MEMF_CLEAR ) )
  48.     {
  49.         /* Init the pointers */
  50.         cp->cp_Chunky = (UBYTE *)((ULONG )cp + sizeof( struct ChunkyPort ) );
  51.  
  52.         cp->cp_Width  = sx;
  53.         cp->cp_Height = sy;
  54.         SetDrMdChk( cp, JAM1 );
  55.         SetABOPenChk( cp, 1, 0, 0 );
  56.  
  57.         return( cp );
  58.     }
  59.     return(NULL);
  60. }
  61. ///
  62. ///"void FreeChunkyPort( struct ChunkyPort * )"
  63. void FreeChunkyPort( struct ChunkyPort *cp )
  64. {
  65.     // Frees allocated ChunkyPort
  66.     if( cp->cp_TxtChunky ) FreeVec( cp->cp_TxtChunky );
  67.     if( cp )    FreeVec( cp );
  68. }
  69. ///
  70. ///"void DrawChunkyPort( struct ChunkyPort *, struct RastPort *, UWORD, UWORD )"
  71. void DrawChunkyPort( struct ChunkyPort *cp, struct RastPort *rp, UWORD x, UWORD y )
  72. {
  73.     // This routine blasts the chunky-buffer over the given rastport at
  74.     // given x/y coordinates
  75.     // Compile this lib with USE_AMIGA_OS defined and you'll get
  76.     // a 100 percent GfxCard compatible lib
  77.  
  78.     #ifdef USE_AMIGA_OS
  79.     struct  BitMap    *bm;
  80.     struct  RastPort  rpt;
  81.     struct  GfxBase *gb = GfxBase;
  82.  
  83.     // Test for V40
  84.     if( gb->LibNode.lib_Version >= 40 ){
  85.         WriteChunkyPixels( rp, x, y, x+cp->cp_Width-1, y+cp->cp_Height-1, cp->cp_Chunky, cp->cp_Width );
  86.  
  87.     } else {
  88.         if( bm = AllocBitMap( cp->cp_Width, 1, 8, BMF_CLEAR, rp->BitMap ) ){
  89.             CopyMem( rp, &rpt, sizeof( struct RastPort ) );
  90.             rpt.Layer  = NULL;
  91.             rpt.BitMap = bm;
  92.  
  93.             WritePixelArray8( rp, x, y, x+cp->cp_Width-1, y+cp->cp_Height-1, cp->cp_Chunky, &rpt );
  94.             FreeBitMap( bm );
  95.         }
  96.     }
  97.     #else
  98.     struct  c2pStruct c2p;
  99.  
  100.     c2p.bmap    = rp->BitMap;
  101.     c2p.startx  = x;
  102.     c2p.starty  = y;
  103.     c2p.width   = cp->cp_Width;
  104.     c2p.height  = cp->cp_Height;
  105.     c2p.ChunkyBuffer  = cp->cp_Chunky;
  106.  
  107.     ChunkyToPlanar( &c2p );
  108.     #endif
  109. }
  110. ///
  111. ///"void DrawChunkyArea( struct ChunkyPort *, struct RastPort *, UWORD, UWORD, UWORD, UWORD )"
  112. void DrawChunkyArea( struct ChunkyPort *cp, struct RastPort *rp, UWORD x, UWORD y, UWORD sizex, UWORD sizey )
  113. {
  114.     // This routine blasts the chunky-buffer over the given rastport at
  115.     // given x/y coordinates and given size
  116.     // Compile this lib with USE_AMIGA_OS defined and you'll get
  117.     // a 100 percent GfxCard compatible lib
  118.  
  119.     struct  c2pStruct c2p;
  120.     struct  BitMap    *bm;
  121.     struct  RastPort  rpt;
  122.  
  123.     #ifdef USE_AMIGA_OS
  124.     if( bm = AllocBitMap( cp->cp_Width, 1, 8, BMF_CLEAR, rp->BitMap ) ){
  125.         CopyMem( rp, &rpt, sizeof( struct RastPort ) );
  126.         rpt.Layer  = NULL;
  127.         rpt.BitMap = bm;
  128.  
  129.         WritePixelArray8( rp, x, y, x+sizex-1, y+sizey-1, cp->cp_Chunky, &rpt );
  130.         FreeBitMap( bm );
  131.     }
  132.     #else
  133.     c2p.bmap    = rp->BitMap;
  134.     c2p.startx  = x;
  135.     c2p.starty  = y;
  136.     c2p.width   = sizex;
  137.     c2p.height  = sizey;
  138.     c2p.ChunkyBuffer  = cp->cp_Chunky;
  139.  
  140.     ChunkyToPlanar( &c2p );
  141.     #endif
  142. }
  143. ///
  144. ///"void InsertChunkyPort( struct ChunkyPort *, struct RastPort *, UWORD, UWORD )"
  145. void InsertChunkyPort( struct ChunkyPort *cp, struct RastPort *rp, UWORD x, UWORD y )
  146. {
  147.     // This function inserts the ChunkyPort into the RastPort at the given
  148.     // coordinates
  149.     // This insertion is done that all bytes that are 0 (ie. Background ) are not
  150.     // set in the destination rport
  151.  
  152.     struct  p2cStruct p2c;
  153.     struct  ChunkyPort  *tmp;
  154.     UBYTE   *src, *dst;
  155.     ULONG   size = cp->cp_Height * cp->cp_Width;
  156.     ULONG   i=0;
  157.     UBYTE   p;
  158.  
  159.     // First allocate a temporary ChunkyPort
  160.     if( tmp = InitChunkyPort( cp->cp_Width, cp->cp_Height ) ){
  161.  
  162.         // convert the destination into chunkyPixels
  163.         p2c.bmap    = rp->BitMap;
  164.         p2c.startx  = x;
  165.         p2c.starty  = y;
  166.         p2c.width   = cp->cp_Width;
  167.         p2c.height  = cp->cp_Height;
  168.         p2c.ChunkyBuffer  = tmp->cp_Chunky;
  169.  
  170.         PlanarToChunky( &p2c );
  171.  
  172.         // copy all pens from src which are not 0 to dst
  173.         src = cp->cp_Chunky;
  174.         dst = tmp->cp_Chunky;
  175.  
  176.         while( i<size )
  177.         {
  178.             p = *src++;
  179.             if( p ) *dst++ = p;
  180.             else    dst++;
  181.             i++;
  182.         }
  183.  
  184.         // finally re-convert the temporary chunkyBuffer
  185.         ChunkyToPlanar( (struct c2pStruct *)&p2c );
  186.  
  187.         // and free temporary buffer
  188.         FreeChunkyPort( tmp );
  189.     }
  190. }
  191. ///
  192. ///"struct ChunkyPort *CreateChunkyFromRastPort( struct RastPort *, UWORD, UWORD, UWORD, UWORD )"
  193. struct ChunkyPort *CreateChunkyFromRastPort( struct RastPort *rp, UWORD x, UWORD y, UWORD sx, UWORD sy )
  194. {
  195.     struct  ChunkyPort  *cp = NULL;
  196.     struct  p2cStruct p2c;
  197.  
  198.     // First create the ChunkyPort
  199.     if( cp = InitChunkyPort( sx, sy ) ){
  200.  
  201.         // Then convert the given rectangle into a ChunkyBuffer
  202.         p2c.bmap    = rp->BitMap;
  203.         p2c.startx  = x;
  204.         p2c.starty  = y;
  205.         p2c.width   = sx;
  206.         p2c.height  = sy;
  207.         p2c.ChunkyBuffer  = cp->cp_Chunky;
  208.  
  209.         PlanarToChunky( &p2c );
  210.  
  211.         return( cp );
  212.     }
  213.     return(NULL);
  214. }
  215. ///
  216. ///"struct ChunkyPort *CreateChunkyFromBitMap( struct BitMap *, UWORD, UWORD, UWORD, UWORD )"
  217. struct ChunkyPort *CreateChunkyFromBitMap( struct BitMap *bm, UWORD x, UWORD y, UWORD sx, UWORD sy )
  218. {
  219.     struct  ChunkyPort  *cp = NULL;
  220.     struct  p2cStruct p2c;
  221.  
  222.     // First create the ChunkyPort
  223.     if( cp = InitChunkyPort( sx, sy ) ){
  224.  
  225.         // Then convert the given rectangle into a ChunkyBuffer
  226.         p2c.bmap    = bm;
  227.         p2c.startx  = x;
  228.         p2c.starty  = y;
  229.         p2c.width   = sx;
  230.         p2c.height  = sy;
  231.         p2c.ChunkyBuffer  = cp->cp_Chunky;
  232.  
  233.         PlanarToChunky( &p2c );
  234.  
  235.         return( cp );
  236.     }
  237.     return(NULL);
  238. }
  239. ///
  240. ///"void SetDrMdChk( ... )"
  241. void SetDrMdChk( struct ChunkyPort *cp, UWORD flags )
  242. {
  243.     cp->cp_Flags = flags;
  244. }
  245. ///
  246. ///"void SetAPenChk( ... )"
  247. inline void SetAPenChk(struct ChunkyPort *cp, UBYTE p )
  248. {
  249.     cp->cp_APen = p;
  250. }
  251. ///
  252. ///"void SetOPenChk( ... )"
  253. inline void SetOPenChk( struct ChunkyPort *cp, UBYTE p )
  254. {
  255.     cp->cp_OPen = p;
  256. }
  257. ///
  258. ///"void SetABOPenChk( ... )"
  259. inline void SetABOPenChk( struct ChunkyPort *cp, UBYTE a, UBYTE b, UBYTE o )
  260. {
  261.     cp->cp_APen = a;
  262.     cp->cp_BPen = b;
  263.     cp->cp_OPen = o;
  264. }
  265. ///
  266. ///"void MoveChk( ... )"
  267. inline void MoveChk( struct ChunkyPort *cp, UWORD x, UWORD y )
  268. {
  269.     // Move(rp,x,y) - replacement
  270.     cp->cp_cx = x;
  271.     cp->cp_cy = y;
  272. }
  273. ///
  274. ///"void SetChkByte( ... )"
  275. inline void SetChkByte( struct ChunkyPort *cp, UBYTE p, UWORD x, UWORD y )
  276. {
  277.     // WritePixel( rp, pen, x, y ) - replacement
  278.     SET_BYTE( cp, p, x, y );
  279. }
  280. ///
  281. ///"UBYTE GetChkByte( ... )"
  282. inline UBYTE GetChkByte( struct ChunkyPort *cp, UWORD x, UWORD y )
  283. {
  284.     // ReadPixel(rp, x, y ) replacement
  285.     return(GET_BYTE( cp, x, y ));
  286. }
  287. ///
  288. ///"void DrawChk( struct ChunkyPort *, UWORD, UWORD )"
  289. inline void DrawChk( struct ChunkyPort *cp, UWORD x2, UWORD y2 )
  290. {
  291.     // Draw(rp, x, y ) replacement with optimized check for
  292.     // horizontal/vertical lines
  293.     const char  p = cp->cp_APen;
  294.     UBYTE   *chk = cp->cp_Chunky;
  295.  
  296.     UWORD   x1 = cp->cp_cx;
  297.     UWORD   y1 = cp->cp_cy;
  298.     int     i, change, s1, s2;
  299.     LONG    x, y, dx, dy, e;
  300.  
  301.     x = x1;
  302.     y = y1;
  303.  
  304.     /* first check, if we should draw a horizontal or vertical line */
  305.     if( y1 == y2 ){
  306.         // We should draw horizontalally
  307.         // Calculate start address and then move the bytes into the buffer
  308.         x = MIN(x1, x2 );
  309.         y = MAX(x1, x2 );
  310.         chk = ((UBYTE *)((ULONG )chk ) + ((cp->cp_Width * y1 ) + x ) );
  311.  
  312.         for( i = x; i < y; i++ ){
  313.             *chk++ = p;
  314.         }
  315.     } else if( x1 == x2 ){
  316.         // We should draw vertically
  317.         // Calculate start address and then move the bytes into the buffer
  318.         x = MIN(y1, y2 );
  319.         y = MAX(y1, y2 );
  320.         chk =